#include "DeviceMessageBuilder.h"
#include <algorithm>
#include <sstream>
#include <iomanip>

namespace DeviceCommons {

    // ==================== Helper Functions Implementation ====================
    
    std::string toHex(const std::vector<uint8_t>& v) {
        std::ostringstream oss;
        for (auto b : v) {
            oss << std::hex << std::setw(2) << std::setfill('0') << (int)b;
        }
        return oss.str();
    }

    void writeBE16(std::vector<uint8_t>& dst, uint16_t v) {
        dst.push_back(static_cast<uint8_t>((v >> 8) & 0xFF));
        dst.push_back(static_cast<uint8_t>(v & 0xFF));
    }

    // ==================== CRC16 Implementation ====================
    uint16_t crc16_impl(const std::vector<uint8_t>& data) {
        uint16_t crc = 0x0000;
        for (uint8_t b : data) {
            crc ^= uint16_t(b) << 8;
            for (int i = 0; i < 8; ++i)
                crc = (crc & 0x8000) ? (crc << 1) ^ 0x8005 : crc << 1;
            crc &= 0xFFFF;
        }
        return crc;
    }

    // ==================== DeviceMessageBuilder Implementation ====================
    
    std::vector<uint8_t> DeviceMessageBuilder::buildBytes() const {
        // 验证必要的设备信息
        if (mainDevice_.did.empty()) {
            throw std::invalid_argument("Main device must be configured before building");
        }
        
        return buildBytesV2();
    }

    std::string DeviceMessageBuilder::buildHex() const {
        return toHex(buildBytes());
    }

    std::vector<uint8_t> DeviceMessageBuilder::buildBytesV2() const {
        std::vector<uint8_t> out;

        // 1. Header (4 bytes) - V2版本先序列化头部
        out.push_back(0xC0); out.push_back(0xBF);  // 魔数字
        out.push_back(PROTOCOL_VERSION);  // 固定V2协议版本
        uint8_t mark = (static_cast<uint8_t>(crcType_) << 4) |
            (static_cast<uint8_t>(reserve2_) << 3) |
            (static_cast<uint8_t>(reserve1_) << 2) |
            (static_cast<uint8_t>(valueType_) << 1) |
            static_cast<uint8_t>(tsFormat_);
        out.push_back(mark);  // 标记字节

        // 2. V2协议：主设备作为设备数组的第一个元素
        std::vector<DeviceInfo> allDevices;
        allDevices.push_back(mainDevice_);  // 主设备必须是第一个
        
        // 添加所有子设备（按添加顺序）
        for (const auto& child : children_) {
            allDevices.push_back(child);
        }

        // 验证设备数量限制
        if (allDevices.size() > 255) {
            throw std::invalid_argument("Total device count exceeds maximum (255)");
        }

        // 序列化设备总数
        out.push_back(static_cast<uint8_t>(allDevices.size()));
        
        // 按顺序序列化所有设备：主设备[0] + 子设备[1,2,3...]
        for (size_t i = 0; i < allDevices.size(); i++) {
            auto deviceData = allDevices[i].serialize();
            out.insert(out.end(), deviceData.begin(), deviceData.end());
        }

        // 3. CRC校验
        appendCRC(out);
        return out;
    }

    void DeviceMessageBuilder::appendCRC(std::vector<uint8_t>& data) const {
        if (crcType_ == CRCType::CRC16) {
            uint16_t crc = crc16_impl(data);
            // 使用小端序存储CRC值，与C#版本保持一致
            data.push_back(static_cast<uint8_t>(crc & 0xFF));        // 低位
            data.push_back(static_cast<uint8_t>((crc >> 8) & 0xFF)); // 高位
        }
        // 可以在此处添加其他CRC类型的支持
        // TODO: 添加CRC32, CRC64等其他类型的支持
    }

    std::future<std::vector<uint8_t>> DeviceMessageBuilder::buildBytesAsync() const {
        return std::async(std::launch::async, [this]() {
            return buildBytes();
        });
    }
    
    std::future<std::string> DeviceMessageBuilder::buildHexAsync() const {
        return std::async(std::launch::async, [this]() {
            return buildHex();
        });
    }

} // namespace DeviceCommons